package com.hengpeng.itfin.domain.imprest.alipay;

import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.itfin.domain.imprest.AbstractImprestProcessor;
import com.hengpeng.itfin.domain.imprest.alipay.util.RSASignature;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfinbase.constants.PaymentConstants;
import com.hengpeng.itfinbase.message.partner.NotifyRequestMsg;
import com.hengpeng.itfinbase.message.partner.NotifyResponseMsg;
import com.hengpeng.itfinbase.message.partner.PayRequestMsg;
import com.hengpeng.itfinbase.message.partner.PayResponseMsg;
import com.hengpeng.itfinbase.persist.Payment;
import com.hengpeng.itfinbase.persist.Payment.PayStatus;
import com.hengpeng.itfinbase.persist.PaymentProvider;


/**
 * <pre>
 * 支付宝-andriod支付网关
 * </pre>
 * @author shanguogang
 * @version 1.0, 2015-8-14
 */
public class AlipayAndriodNewImprestProcessor  extends AbstractImprestProcessor {
	
	private final static Log logger = LogFactory.getLog(AlipayAndriodNewImprestProcessor.class);
	
	private static final String ALIPAYANDRIOD_CONFIG_PUBLICKEYID = "publicKeyId";
	
	private String publicKeyId;
	
	public AlipayAndriodNewImprestProcessor(ServiceFactory serviceFactory, PaymentProvider provider) {
		super(serviceFactory, provider);
		publicKeyId = provider.getExtConfigs().get(ALIPAYANDRIOD_CONFIG_PUBLICKEYID);
	}


	@Override
	public void payRequest(PayRequestMsg request, PayResponseMsg response) {
		// TODO Auto-generated method stub
		response.setOrdId(request.getOrdId());//生成订单号
	}
	@Override
	public void payNotify(NotifyRequestMsg request, NotifyResponseMsg response) {
		Map<String, String> parameters = request.getParameter();
        if (parameters == null || parameters.size() < 1) {
        	return;
        }
        /**
         * 对参数进行排序
         */
        TreeMap<String, String> treeMap = new TreeMap<String, String>(new Comparator<String>(){  
            public int compare(String o1, String o2) {  
                return o1.compareTo(o2);  
            }     
        });
    	Set<Entry<String,String>> set = parameters.entrySet();  
	    for (Entry<String,String> entry : set) {  
	        treeMap.put(entry.getKey(), entry.getValue());
	    } 
	    /**
	     * 生成验签参数串
	     */
	    StringBuffer verifySbuff = new StringBuffer();
	    for (Object o : treeMap.keySet()) {  
            if ((o.toString().equalsIgnoreCase("sign_type"))
					|| (o.toString().equalsIgnoreCase("sign")))
			{
				continue;
			}
			verifySbuff.append(o.toString()).append("=").append(treeMap.get(o)).append("&");
        }  
		if (verifySbuff.length() > 0)
		{
			verifySbuff = new StringBuffer(verifySbuff.substring(0, verifySbuff.length() - 1));
		} else {
			verifySbuff.append("");
		}
		logger.info("providerid{"+ this.provider.getId() +"},签名参数串{"+ verifySbuff.toString() +"},支付宝返回签名{"+ parameters.get("sign").replaceAll(" ", "+") +"}");
		boolean verified = verifyRSA(verifySbuff.toString(), parameters.get("sign").replaceAll(" ", "+"), publicKeyId);
		if (verified)
		{
			// 成功
			try
			{
				String trade_status = parameters.get("trade_status");
				String money = parameters.get("total_fee");
				String orderNo = parameters.get("out_trade_no");
				Double doubleMoney = Double.parseDouble(money) * 100;
				/**
				 * 交易成功 trade_status=TRADE_FINISHED (若高级即时到账则trade_status=TRADE_SUCCESS)
				 */
				if ("TRADE_FINISHED".equals(trade_status) || "TRADE_SUCCESS".equals(trade_status))
				{
					response.setProviderId(this.provider.getId());
	    			response.setOrdId(orderNo);
					response.setTransAmt(money);
					ServiceResult<Payment> result = serviceFactory.getPayService().dealPayResult(
							request.getProviderId(), orderNo, doubleMoney.longValue(), PayStatus.SUCCESS, "支付成功");
					if (!result.getIsSuccess()) {
						logger.info("providerid{"+ this.provider.getId() +"},本地处理失败!失败信息:" + result.getMessage());
						response.setRespCode(result.getCode());
						response.setRespDesc(result.getMessage());
					} else {
						response.setMerchantId(this.provider.getMerchantId());
						response.setTransAmt(money);
						response.setOrdId(orderNo);
					}
				}
				else
				{
					logger.info("充值失败,providerid{"+ this.provider.getId() +"},订单号{" + (orderNo == null ? "" : orderNo) + "},订单状态{"+ (trade_status == null ? "" : trade_status) +"}");
					response.setRespCode(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRCODE_OTHER);
					response.setRespDesc("充值失败！");
					ServiceResult<Payment> result = serviceFactory.getPayService().dealPayResult(
							response.getProviderId(), response.getOrdId(), doubleMoney.longValue(), PayStatus.FAILED,
							response.getRespDesc());
				}
			}
			catch (Exception e)
			{
				logger.info("充值回调发生异常!providerid{"+ this.provider.getId() +"}, 异常信息:" + e.getMessage());
				e.printStackTrace();
				response.setRespCode(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRCODE_OTHER);
				response.setRespDesc("处理失败，若确认已付款，请联系客服冲正！");
			}
		}
		else
		{
			logger.info("providerid{"+ this.provider.getId() +"},回调验签失败!");
			// 验签失败
			response.setRespCode(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRCODE_DIGESTERROR);
			response.setRespDesc(PaymentConstants.PAYMENT_TRANSMESSAGE_ERRMSG_DIGESTERROR);
		}
	}
	/**
	 * RSA验签
	 * @param verifyData 待签名数据
	 * @param sign 支付宝返回的签名
	 * @param key 支付宝公钥
	 * @return
	 */
	private boolean verifyRSA(String verifyData, String sign, String publicKey)
	{
		try
		{
			return RSASignature.doCheck(verifyData, sign, publicKey, "UTF-8");
		}
		catch (Exception e)
		{
			logger.info("RSA待验签数据:" + verifyData + "支付宝返回的签名：" + sign);
			e.printStackTrace();
		}
		return false;
	}
}
